<?php

namespace App\Http\Requests;

use App\Exceptions\ApiErrCode;
use App\Exceptions\ApiException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Database\Query\Builder;
use Illuminate\Foundation\Http\FormRequest;

/**
 * Class ApiRequest
 *
 * @property string|null per_page
 * @property string|null page
 *
 * @package App\Http\Requests
 */
class ApiRequest extends FormRequest
{
    const MAX_INT = 2147483647; // 字段类型是int时，可以提交的最大值
    const MAX_STRING = 255;     // 字符串类型的值，最大字符数255
    const MAX_URL = 2048;     // 字符串 URL 类型的值，最大字符数 2048 字节

    protected $errors_glue = " ";

    /**
     * @var int
     */
    protected $auth_error_code = ApiErrCode::AUTHORIZE_ERROR_ID_UNKNOWN;

    /**
     * @var string
     */
    protected $auth_error_msg = "Api authorization failed error";

    /**
     * @param Validator $validator
     *
     * @throws ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    protected function failedValidation(Validator $validator)
    {
        throw new ApiException(
            ApiErrCode::REQUEST_PARAMS_ERROR,
            $this->errorToString(
                $validator->errors()->messages(),
                $this->errors_glue
            )
        );
    }
    
    /**
     * @throws ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    protected function failedAuthorization()
    {
        throw new ApiException($this->auth_error_code, $this->auth_error_msg);
    }


    /**
     * 数组错误信息转成分隔开的字符串
     *
     * @test
     * @see WechatRequestTest::test_wx_req_format_errors_to_string()
     *
     * @param array $rules_errors
     * @param string $glue
     * @return string
     */
    public function errorToString(array $rules_errors, string $glue)
    {
        return array_reduce($rules_errors, function ($before, $current) use ($glue) {
            $prefix = $before ? $glue : '';
            return $before . $prefix . implode($glue, $current);
        }, '');
    }

    /**
     * @param $conditions
     *
     * @return \Closure
     */
    protected function closureWhere(array $conditions): \Closure
    {
        return function (Builder $query) use ($conditions) {
            return $query->where($conditions);
        };
    }

    /**
     * @param int $code
     * @param string $msg
     */
    protected function setAuthError(int $code, string $msg)
    {
        $this->auth_error_code = $code;
        $this->auth_error_msg = $msg;
    }
}
